home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
476-500
/
disk_497
/
nlcalc
/
source
/
cmain.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
9KB
|
328 lines
/*
* CALC Provides a calculator that opens on the active screen when
* you press a specific key sequence. Otherwise, the program
* waits quitely in the background.
*
* Copyright 1989 by Davide P. Cervone.
* You may use this code, provided this copyright notice is kept intact.
*/
#define INTUITION_PREFERENCES_H /* don't need 'em */
#include <intuition/intuitionbase.h>
#include <libraries/dos.h>
#include <proto/intuition.h>
#include <proto/exec.h>
#include "cHandler.h"
#include "cSetup.h"
#include "cKeys.h"
#define SCREENTITLE\
"Screen Calculator v3.1 Copyright (c) 1989 by Davide P. Cervone"
#define SIGNALCLOSE TRUE
#define NOSIGNAL FALSE
#define INTUITION_REV 0
#define GRAPHICS_REV 0
#define ERROR_EXIT 10
#define GADGFLAGS WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH
#define IDCMPFLAGS\
CLOSEWINDOW | GADGETUP | GADGETDOWN | VANILLAKEY |\
NOCAREREFRESH | ACTIVEWINDOW
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
static struct NewWindow NewWindow =
{
-1,-1, WINDW,WINDH, -1,-1, IDCMPFLAGS,
SIMPLE_REFRESH | ACTIVATE | GADGFLAGS, NULL, NULL,
#ifdef SWINDOWS
"::",
#else
NULL,
#endif
NULL, NULL, 20,20, -1,-1, WBENCHSCREEN
};
struct Screen *CalcScreen; /* the screen containing the calculator */
struct Window *CalcWindow; /* the calculator window */
struct RastPort *rp; /* the windows' rast port */
static LONG CalcWMask; /* the calculator handler task */
/*
* CloseCalcWindow()
*
* If the window is open, save the calculator position for later, and
* close the window. Clear the pointers to the screen and window, and
* forget which signal we used to use for the window.
*
* If we were supposed to let someone know when the window was closed,
* then signal the proper task.
*/
void CloseCalcWindow(signal)
int signal;
{
if (CalcWindow != NULL)
{
NewWindow.LeftEdge = CalcWindow->LeftEdge;
NewWindow.TopEdge = CalcWindow->TopEdge;
CloseWindow(CalcWindow);
CalcWindow = NULL;
CalcScreen = NULL;
CalcWMask = 0;
}
#ifndef SWINDOWS
if (signal) SignalClosed();
#endif
}
/*
* OpenCalcWindow()
*
* If we have a screen to open on, then set the window type and screen
* pointer. Check that the calculator is positioned within the given
* screen size. Open the calulator. If we were successful, then get the
* rastport pointer, and set the mask for the message port.
*/
static void OpenCalcWindow(theScreen)
struct Screen *theScreen;
{
extern struct Window *OpenWindow();
if (theScreen)
{
CalcScreen = theScreen;
#ifndef NL_DAEMON
if (theScreen->BitMap.Depth == 1)
{
NewWindow.DetailPen = 0;
NewWindow.BlockPen = 1;
} else {
NewWindow.DetailPen = DARKPEN;
NewWindow.BlockPen = BACKPEN;
}
#endif
#ifndef SWINDOWS
NewWindow.Screen = CalcScreen;
NewWindow.Type = CUSTOMSCREEN;
#endif
if (NewWindow.LeftEdge < 0 || NewWindow.TopEdge < 0 ||
NewWindow.LeftEdge + NewWindow.Width > CalcScreen->Width ||
NewWindow.TopEdge + NewWindow.Height > CalcScreen->Height)
{
NewWindow.LeftEdge = (CalcScreen->Width - NewWindow.Width)/2;
NewWindow.TopEdge = (CalcScreen->Height - NewWindow.Height)/2;
if (NewWindow.LeftEdge < 0) NewWindow.LeftEdge = 0;
if (NewWindow.TopEdge < 0) NewWindow.TopEdge = 0;
}
if ((CalcWindow = OpenWindow(&NewWindow)) != NULL)
{
rp = CalcWindow->RPort;
CalcWMask = (1<<CalcWindow->UserPort->mp_SigBit);
CalcScreen = CalcWindow->WScreen;
} else {
DisplayBeep(theScreen);
}
}
}
/*
* SetupGadgets()
*
* This fixes the standard Intuition gadgets so that their images are
* the New Look images. This makes the Calulator look cool. Once
* the changes have been made, refresh the window frame so that the new
* gadgets show up, then add the rest of the Calc gadgets into the window,
* and refresh them so that they show up.
*/
static void SetupGadgets()
{
#ifndef NL_DAEMON
struct Gadget *theGadget = CalcWindow->FirstGadget;
extern struct Image UpFrontImage,DownBackImage,CloseImage;
while (theGadget)
{
switch(theGadget->GadgetType & ~SYSGADGET)
{
case WUPFRONT:
if (CalcScreen->BitMap.Depth > 1)
{
theGadget->GadgetRender = (APTR)&UpFrontImage;
theGadget->LeftEdge = -UpFrontImage.Width + 1;
theGadget->Width = UpFrontImage.Width;
}
break;
case WDOWNBACK:
if (CalcScreen->BitMap.Depth > 1)
{
theGadget->GadgetRender = (APTR)&DownBackImage;
theGadget->LeftEdge = -UpFrontImage.Width-DownBackImage.Width+1;
theGadget->Width = DownBackImage.Width;
}
break;
case CLOSE:
theGadget->GadgetRender = (APTR)&CloseImage;
theGadget->LeftEdge = 0;
theGadget->Width = CloseImage.Width;
break;
}
theGadget = theGadget->NextGadget;
}
RefreshWindowFrame(CalcWindow);
#endif
AddGList(CalcWindow,&CalcGadget[0],-1,GADGET_COUNT,NULL);
RefreshGadgets(&CalcGadget[0],CalcWindow,NULL);
}
#define CloseCalculator CloseCalcWindow
/*
* OpenCalculator()
*
* If the active screen is not the one where the calculator already exists,
* then if the calculator is already open, close it (don't signal anyone).
* Open the calculator on the new screen. If the calculator opened OK,
* the setup the gadgets and set the screen title.
*/
static void OpenCalculator()
{
if (IntuitionBase->ActiveScreen != CalcScreen)
{
if (CalcWindow) CloseCalculator(NOSIGNAL);
OpenCalcWindow(IntuitionBase->ActiveScreen);
if (CalcWindow)
{
SetupGadgets();
SetWindowTitles(CalcWindow,-1,SCREENTITLE);
}
}
}
/*
* WaitForAction()
*
* The main Calculator event loop.
*
* While we have not been asked to exit,
* if the calc window is open somewhere,
* Check for new messages from the calculator window.
* If any (and the calculator hasn't been closed or asked to exit) then
* get the class code and gadget pointer from the IntuiMessage,
* and reply the message.
* For CLOSWINDOW events, set the flag indicating we should close.
* For keyboard messages, do the appropriate action.
* For gadget messages, do the proper gadget action.
* For activation events, refresh the lines in the Drag Bar.
* When all the messages have been processed,
* if we were asked to close the window, then do so.
* If we haven't been asked to exit, then wait for more messages.
* If we get an ENDSIGNAL from the loader, set the done flag.
* If we get a signal to open the calculator, then do so.
* If we get a signal to close the calculator (from a CloseScreen
* call), then do so.
*/
#define NEWMESSAGE (theMessage = GetMsg(CalcWindow->UserPort))
#ifndef SWINDOWS
#define MESSAGEWAIT Wait(CalcSMask|CalcCMask|CalcWMask|ENDSIGNAL)
#else
#define MESSAGEWAIT Wait(CalcSMask|CalcWMask|ENDSIGNAL)
#endif
static void WaitForAction()
{
struct IntuiMessage *theMessage;
extern struct IntuiMessage *GetMsg();
int Class, Code;
struct Gadget *theGadget;
LONG Signals;
int NotClosed;
int NotDone = TRUE;
while (NotDone)
{
if (CalcWindow)
{
NotClosed = TRUE;
while (NEWMESSAGE && NotDone && NotClosed)
{
Class = theMessage->Class;
Code = theMessage->Code;
theGadget = (struct Gadget *)theMessage->IAddress;
ReplyMsg(theMessage);
switch(Class)
{
case CLOSEWINDOW:
NotClosed = FALSE;
break;
case VANILLAKEY:
NotClosed = DoKey(Code);
break;
case GADGETUP:
case GADGETDOWN:
DoGadget(theGadget);
break;
case ACTIVEWINDOW:
RefreshGList(&CalcGadget[GADG_BRDR],CalcWindow,NULL,1);
break;
}
}
if (NotClosed == FALSE) CloseCalculator(NOSIGNAL);
}
if (NotDone) Signals = MESSAGEWAIT;
if (Signals & ENDSIGNAL) NotDone = FALSE;
if (Signals & CalcSMask) OpenCalculator();
#ifndef SWINDOWS
if (Signals & CalcCMask) CloseCalculator(SIGNALCLOSE);
#endif
}
}
/*
* _main()
*
* Initialize the calculator.
* As long as we have not been asked to exit, do the main event loop.
* Once the main event loop end, we have been asked to exit this task.
* close the calculator if it is open, and try to confirm with the loader
* that we can exit properly. If not, then keep running, otherwise
* call our exit routine.
*/
void _main()
{
int NotDone = TRUE;
InitCalc();
while (NotDone)
{
WaitForAction();
CloseCalculator(NOSIGNAL);
NotDone = ConfirmExit();
}
cExit();
}